﻿using DoNet.Core;
using DoNet.System.IRepositories;
using DoNet.System.Models;
using System.Linq.Expressions;

namespace DoNet.System.Repositories
{
    public class TokenRepository : BaseRepository<Token>, ITokenRepository
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceProvider"></param>
        public TokenRepository(IServiceProvider serviceProvider) : base(serviceProvider)
        { }
        #region 同步方法

        #region 修改
        /// <summary>
        /// 同步更新AccessToken
        /// </summary>
        /// <param name="token"></param>
        /// <param name="accessExpire"></param>
        /// <param name="lastModifyUserId"></param>
        /// <param name="lastModifyTime"></param>
        /// <param name="id"></param>
        /// <returns>执行成功返回true，否则为false。</returns>
        public bool Update(string token, int accessExpire, long lastModifyUserId, DateTime lastModifyTime, long id)
        {
            Expression<Func<Token, Token>> columns = x => new Token() { AccessToken = token, AccessExpires = accessExpire, AccessExpiresDate= DateTime.UtcNow.AddMinutes(accessExpire), LastModifyUserId = lastModifyUserId, LastModifyTime = lastModifyTime };
            Expression<Func<Token, bool>> whereExpression = x => x.Id == id && !x.DeleteMark;
            return Update(columns, whereExpression);
        }
        #endregion 修改

        #region 查询
        /// <summary>
        /// 同步获取当前AppId未过期的Token
        /// </summary>
        /// <param name="appId"></param>
        /// <returns></returns>
        public Token GetTokenByAppId(string appId)
        {
            return Db.Queryable<Token>().Where(x => x.AppId == appId && !x.DeleteMark && x.AccessExpiresDate > DateTime.UtcNow).First();
        }
        /// <summary>
        /// 同步获取当前token或者刷新token
        /// </summary>
        /// <param name="token">当前token或者刷新token</param>
        /// <returns></returns>
        public Token GetTokenIsRevoked(string token)
        {
            return Db.Queryable<Token>().Where(x => (x.AccessToken == token || x.RefreshToken == token) && x.DeleteMark).First();
        }
        /// <summary>
        /// 同步根据刷新token获取当前token
        /// </summary>
        /// <param name="refreshToken">刷新token</param>
        /// <returns></returns>
        public Token GetTokenByRefreshToken(string refreshToken)
        {
            return Db.Queryable<Token>().Where(x => x.RefreshToken == refreshToken && !x.DeleteMark).First();
        }
        #endregion 查询

        #endregion 同步方法

        #region 异步方法

        #region 修改
        /// <summary>
        /// 异步更新AccessToken
        /// </summary>
        /// <param name="token"></param>
        /// <param name="accessExpire"></param>
        /// <param name="lastModifyUserId"></param>
        /// <param name="lastModifyTime"></param>
        /// <param name="id"></param>
        /// <returns>执行成功返回true，否则为false。</returns>
        public async Task<bool> UpdateAsync(string token, int accessExpire, long lastModifyUserId, DateTime lastModifyTime, long id)
        {
            Expression<Func<Token, Token>> columns = x => new Token() { AccessToken = token, AccessExpires = accessExpire, AccessExpiresDate = DateTime.UtcNow.AddMinutes(accessExpire), LastModifyUserId = lastModifyUserId, LastModifyTime = lastModifyTime };
            Expression<Func<Token, bool>> whereExpression = x => x.Id == id && !x.DeleteMark;
            return await UpdateAsync(columns, whereExpression);
        }
        #endregion 修改

        #region 查询
        /// <summary>
        /// 异步获取当前AppId未过期的Token
        /// </summary>
        /// <param name="appId"></param>
        /// <returns></returns>
        public async Task<Token> GetTokenByAppIdAsync(string appId)
        {
            return await Db.Queryable<Token>().Where(x => x.AppId == appId && !x.DeleteMark && x.AccessExpiresDate > DateTime.UtcNow).FirstAsync();
        }
        /// <summary>
        /// 异步获取当前token或者刷新token
        /// </summary>
        /// <param name="token">当前token或者刷新token</param>
        /// <returns></returns>
        public async Task<Token> GetTokenIsRevokedAsync(string token)
        {
            return await Db.Queryable<Token>().Where(x => (x.AccessToken == token || x.RefreshToken == token) && x.DeleteMark).FirstAsync();
        }
        /// <summary>
        /// 异步根据刷新token获取当前token
        /// </summary>
        /// <param name="refreshToken">刷新token</param>
        /// <returns></returns>
        public async Task<Token> GetTokenByRefreshTokenAsync(string refreshToken)
        {
            return await Db.Queryable<Token>().Where(x => x.RefreshToken == refreshToken && !x.DeleteMark).FirstAsync();
        }
        #endregion 查询

        #endregion 异步方法
    }
}